package com.dxj.exception;

import com.dxj.response.R;
import com.dxj.sysEnum.SysHttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author dxj
 * @Description 全局处理异常
 * @date 2024/7/18 19:16
 */
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 用户不存在错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = UsernameNotFoundException.class)
    public R<String> usernameNotFoundException(UsernameNotFoundException e) {
        logger.error("用户不存在={}", e.getMessage());
        return R.fail(e.getMessage());
    }

    /**
     * 用户密码错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = UserPasswordNotMatchException.class)
    public R<String> UserPasswordNotMatchException(UserPasswordNotMatchException e) {
        logger.error("用户密码错误={}", e.getMessage());
        return R.fail(e.getMessage());
    }


    /**
     * 系统异常错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public R<Void> exception(Exception e) {
        logger.error("全局异常信息 ex={}", e.getMessage());
        return R.fail();
    }

    /**
     * 参数校验错误
     *
     * @param e
     * @param request
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public R<Object> exception(MethodArgumentNotValidException e, HttpServletRequest request) {
        Map<String, String> result = new HashMap<>();
        //获取校验信息，包含所有失败的检验信息
        BindingResult bindingResult = e.getBindingResult();
        //记录请求方法和请求URL
        logger.error("请求[ {} ] {} 的参数校验发生错误", request.getMethod(), request.getRequestURL());
        //遍历所有错误，将每个错误字段和错误的消息存入Map中
        for (ObjectError objectError : bindingResult.getAllErrors()) {
            FieldError fieldError = (FieldError) objectError;
            logger.error("参数 {} = {} 校验错误：{}", fieldError.getField(), fieldError.getRejectedValue(), fieldError.getDefaultMessage());
            result.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        return R.fail(SysHttpStatus.PARAMRROR, result);
    }

    /**
     * 系统未知异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public R<Void> CustomException(CustomException e) {
        logger.error("自定义异常信息 ex={}", e.getMessage());
        return R.fail();
    }


    /**
     * 请求方式不匹配异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public R<Void> handleHttpRequestMethodNotSupportedException(
            HttpRequestMethodNotSupportedException e) {
        logger.error("请求方式不匹配异常 ex={}", e.getMessage());
        return R.fail(SysHttpStatus.UNSUPPORTED);
    }

    /**
     * 获取用户信息异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    public R<Void> serviceException(ServiceException e) {
        logger.error("获取用户信息异常 ex={}", e.getMessage());
        return R.fail(SysHttpStatus.UNUSERINFOERROR);
    }
}
